package vek.GUI.SearchAndListView;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import vek.Debug;
import vek.Main2;
import vek.TerminalSettings;
import vek.Update.UpdateTimer;
import vek.Update.Updater;
import vek.controllers.SearchAndList.NavigationPanelController;

/**
 * This class provides the GUI for the search function.
 * This JPanel is placed at the bottom on the screen and contains buttons to facilitate searching through the POIs.
 * @author Christian, Michal og Jakob (Hold 1, gruppe 2)
 */
public class NavigationPanel extends JPanel{
    
    private String nameOfFontOnButtons = "Arial";
    private double factorToMultiplyWidthOfButtons;
    private int fontSize;
    private int standardWidthOfButtons;
    private int standardHeightOfButtons;
    private Dimension prefferedSize;
    private NavigationPanelController controller;
    private JButton help;
    private JButton findViaName;
    private JButton findViaType;
    private JButton findViaRoad;
    private JButton findViaPhoneNumber;
    private JCheckBox isOpen;
    private JCheckBox hasToilets;
    private JButton newSearch;
    private JLabel withinTextField;
    private JLabel metersTextField;
    private JSpinner withinXMeters;
    private JPopupMenu typePopup;
    private JLabel currentSearching;
    private JTextField searchToString;
    private String textOnCurrentSearching = "Din søgning: ";
    private boolean popUpSizeSet;
    
    private JButton updateButton;
    
    
    public NavigationPanel(Dimension size)
    {
        prefferedSize = size;
        setPreferredSize( prefferedSize );
        factorToMultiplyWidthOfButtons = (prefferedSize.getWidth() / 1050);
        setFontSize();
        
        standardHeightOfButtons = (int)(prefferedSize.getHeight() / 2.5);
        
        // methods
        createButtons();
        createLayout();
        addContents();
        
        addUpdateButton();
    }
    
    /**
     * Sets the font size depending on the screen width
     */
    
    
    private void setFontSize()
    {
        if(prefferedSize.getWidth() < 1024 )
        {
            fontSize = 10;
        }
        else if(prefferedSize.getWidth() < 1200 )
        {
            fontSize = 12;
        }
            
        else
        {
            fontSize = 14;
        }
    }
    
    /**
     * Makes this panel visible
     */
    
    public void showPanel()
    {
        setVisible(true);
        revalidate();
    }
    
    /**
     * Hides this panel
     */
    
    public void hidePanel()
    {
        setVisible(false);
        revalidate();
    }
    
    /**
     * Creates the buttons on this panel, sets their size, sets the font and sets their name. Note that the code used for the various buttons are almost identical. 
     */
    
    private void createButtons()
    {
        help = new JButton("Hjælp");
        help.setName("helpbutton");
        help.setPreferredSize(new Dimension( (int)
                (help.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        
        
        findViaName = new JButton("Find via navn");
        findViaName.setName("findvianame");
        findViaName.setPreferredSize(new Dimension( (int)
                (findViaName.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        findViaName.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize));
        findViaName.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        findViaType = new JButton("Find via type");
        findViaType.setName("findviatype");
        findViaType.setPreferredSize(new Dimension( (int)
                (findViaType.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        findViaType.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        findViaType.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        findViaRoad = new JButton("Find via vejnavn");
        findViaRoad.setName("findviaroad");
        findViaRoad.setPreferredSize(new Dimension( (int)
                (findViaRoad.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        findViaRoad.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        findViaRoad.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        findViaPhoneNumber = new JButton("Find via telefonnummer");  
        findViaPhoneNumber.setName("findviaphonenumber");
        findViaPhoneNumber.setPreferredSize(new Dimension( (int)
                (findViaPhoneNumber.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        findViaPhoneNumber.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        findViaPhoneNumber.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        isOpen = new JCheckBox("Er åben");
        isOpen.setName("isopen");
        isOpen.setPreferredSize(new Dimension( (int)
                (isOpen.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        isOpen.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        isOpen.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        hasToilets = new JCheckBox("Har toiletter");
        hasToilets.setName("hastoilets");
        hasToilets.setPreferredSize(new Dimension( (int)
                (hasToilets.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        hasToilets.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        hasToilets.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        newSearch = new JButton("Ny søgning");
        newSearch.setName("newsearch");
        newSearch.setPreferredSize(new Dimension( (int)
                (newSearch.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                (int)(standardHeightOfButtons * 1.5))  );
        newSearch.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        newSearch.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
        
        withinTextField = new JLabel("indenfor");
        withinTextField.setPreferredSize(new Dimension( (int)
                (withinTextField.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        withinTextField.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        
        metersTextField = new JLabel("meter");
        metersTextField.setPreferredSize(new Dimension( (int)
                (metersTextField.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        metersTextField.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        
        
        withinXMeters = new JSpinner(new SpinnerNumberModel(0, 0, 3000, 100));
        withinXMeters.setPreferredSize(new Dimension(60,30));
        withinXMeters.setPreferredSize(new Dimension( (int)
                (withinXMeters.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
        withinXMeters.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        withinXMeters.getEditor().setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
        
        currentSearching = new JLabel(textOnCurrentSearching);
        currentSearching.setPreferredSize(new Dimension( (int)
                (prefferedSize.getWidth() ),
                standardHeightOfButtons / 3)  );
        currentSearching.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
                
        typePopup = new JPopupMenu("test");
        typePopup.setName("typepopup");
        
        
        
        
    }
    
    /**
     * Adds the buttons to this component
     */
    
    private void addContents()
    {
        add(currentSearching);
        add(findViaName);
        add(findViaType);
        add(findViaRoad);
        add(findViaPhoneNumber);
        add(withinTextField);
        add(withinXMeters);
        add(metersTextField);
        //add(isOpen);
        add(hasToilets);
        add(newSearch, BorderLayout.EAST);
        
    }
    
    /**
     * Creates the layout for this component. The layout used is BorderLayout
     */
   
    
    private void createLayout()
    {
        //setLayout(new BorderLayout());
    }
    
    /**
     * Adds the NavigationPanelController to the buttons
     */
    
    private void addControllerToComponents()
    {
        findViaName.addActionListener(controller);
        findViaType.addActionListener(controller);
        findViaRoad.addActionListener(controller);
        findViaPhoneNumber.addActionListener(controller);
        withinXMeters.addChangeListener(controller);
        //isOpen.addActionListener(controller);
        hasToilets.addActionListener(controller);
        newSearch.addActionListener(controller);
    }
    
    /**
     * Sets the NavigationPanelController to the one given in the parameter.
     * @param npc the NavigationPanelController to be used by the buttons in this panel
     */
    
    public void setController(NavigationPanelController npc)
    {
       controller = npc;   
       addControllerToComponents();
    }
    
    /**
     * Gets the current value of the JSPinner, that is it gets the amount of meters which the POI shown must be within
     * @return current value of the JSPinner WithinXMeters
     */
    
    public double getCurrentValueInWithInXMetersSpinner()
    {
        SpinnerNumberModel snm = (SpinnerNumberModel) withinXMeters.getModel();
        return snm.getNumber().doubleValue();
    }
    
    /**
     * Loads the popup menu with a list of types of POIs as Strings and then shows a popup menu containing these strings.
     * @param comp the component calling to show the popup
     * @param list a list of strings which the popup menu is supposed to contain
     */
    
    public void loadAndShowTypePopup(Component comp, ArrayList<String> list)
    {
        loadPopupMenuWithItemsFromDatabase(list);
        int height = (int)typePopup.getPreferredSize().getHeight();
        if(popUpSizeSet == false)
        {
            typePopup.setPreferredSize(new Dimension( (int)
                (typePopup.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons ),
                standardHeightOfButtons)  );
            popUpSizeSet = true;
        }
        
        typePopup.show(comp, 0, -height);
    }
    
    /**
     * Puts the strings into the popup menu
     * @param list List of types of POIs which the popup menu should show
     */
    
    private void loadPopupMenuWithItemsFromDatabase(ArrayList<String> list)
    {
        typePopup.removeAll();
        for(int i = 0; i < list.size(); i++)
        {
            JMenuItem menuitem = new JMenuItem(list.get(i));
            menuitem.addActionListener(controller);
            menuitem.setName("menuitem" + i);
            menuitem.setFont(new Font(nameOfFontOnButtons, Font.BOLD, (int) (fontSize  * 0.85) ));
            typePopup.add( menuitem );
            
        }
    }
    
    /**
     * Gets the JSpinner which handles the "only show POIs within X meters" function
     * @return the JSpinner which handles the "only show POIs within X meters" function
     */
    
    public JSpinner getWithXMetersSpinner()
    {
        return withinXMeters;
    }
    
    /**
     * Gets the isOpen check box
     * @return the isOpen check box
     */
    
    public JCheckBox getisOpenCheckBox()
    {
        return isOpen;
    }
    
    /**
     * Gets the hasToilets check box
     * @return the hasToilets check box
     */
    public JCheckBox gethasToiletsCheckBox()
    {
        return hasToilets;
    }
    
    /**
     * Sets the text of the "currently searching for" JLabel, used to show what the user is searching for at the moment.
     * @param s the text which is to be put on the JLabel which shows what the user is searching for
     */
    
    public void setTextOnCurrentSearchingLabel(String s)
    {
        currentSearching.setText(textOnCurrentSearching + s);
    }
    
    /**
     * Adds an update button which updates the XML files, used solely for debugging purposes.
     */
    
    public void addUpdateButton()
    {
        if(Debug.DEBUGON) // checks if the program is in debug mode
        {
            updateButton = new JButton("Update");
            updateButton.setName("Update");
            updateButton.setPreferredSize(new Dimension( (int)
                (updateButton.getPreferredSize().getWidth() * factorToMultiplyWidthOfButtons / 1.5 ),
                standardHeightOfButtons)  );
            updateButton.setFont(new Font(nameOfFontOnButtons, Font.BOLD, fontSize  ));
            updateButton.setMargin(new Insets(0,0,0,0)); // prevents text on button from being replaced with "..."
            updateButton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    Updater update = new Updater(Main2.getDBC());
                    UpdateTimer updateTimer = UpdateTimer.getUpdateTimer();
                    updateTimer.schedule(update, 0);
                }
            });
        }
        
        add(updateButton);
    }
    

}
